#include "Texture2DDescription.h"

using namespace Renderer;


bool Renderer::Texture2DDescription::Equals(const Texture2DDescription& other)
{
	return ((_width == other.GetWidth()) &&
		(_height == other.GetHeight()) &&
		(_format == other.GetTextureFormat()) &&
		(_generateMipmaps == other.IsGernateMipmaps()));
}

bool Renderer::Texture2DDescription::operator!=(const Texture2DDescription& other)
{
	return !(this->Equals(other));
}

bool Renderer::Texture2DDescription::operator==(const Texture2DDescription & other)
{
	return this->Equals(other);
}

int Renderer::Texture2DDescription::SizeInBytes(TextureFormat format)
{
	switch (format)
	{
	case TextureFormat::RedGreenBlue8:
		return 3;
	case TextureFormat::RedGreenBlue16:
		return 6;
	case TextureFormat::RedGreenBlueAlpha8:
		return 4;
	case TextureFormat::RedGreenBlue10A2:
		return 4;
	case TextureFormat::RedGreenBlueAlpha16:
		return 8;
	case TextureFormat::Depth16:
		return 2;
	case TextureFormat::Depth24:
		return 3;
	case TextureFormat::Red8:
		return 1;
	case TextureFormat::Red16:
		return 2;
	case TextureFormat::RedGreen8:
		return 2;
	case TextureFormat::RedGreen16:
		return 4;
	case TextureFormat::Red16f:
		return 2;
	case TextureFormat::Red32f:
		return 4;
	case TextureFormat::RedGreen16f:
		return 4;
	case TextureFormat::RedGreen32f:
		return 8;
	case TextureFormat::Red8i:
		return 1;
	case TextureFormat::Red8ui:
		return 1;
	case TextureFormat::Red16i:
		return 2;
	case TextureFormat::Red16ui:
		return 2;
	case TextureFormat::Red32i:
		return 4;
	case TextureFormat::Red32ui:
		return 4;
	case TextureFormat::RedGreen8i:
		return 2;
	case TextureFormat::RedGreen8ui:
		return 2;
	case TextureFormat::RedGreen16i:
		return 4;
	case TextureFormat::RedGreen16ui:
		return 4;
	case TextureFormat::RedGreen32i:
		return 8;
	case TextureFormat::RedGreen32ui:
		return 8;
	case TextureFormat::RedGreenBlueAlpha32f:
		return 16;
	case TextureFormat::RedGreenBlue32f:
		return 12;
	case TextureFormat::RedGreenBlueAlpha16f:
		return 8;
	case TextureFormat::RedGreenBlue16f:
		return 6;
	case TextureFormat::Depth24Stencil8:
		return 4;
	case TextureFormat::Red11fGreen11fBlue10f:
		return 4;
	case TextureFormat::RedGreenBlue9E5:
		return 4;
	case TextureFormat::SRedGreenBlue8:
		return 3;
	case TextureFormat::SRedGreenBlue8Alpha8:
		return 4;
	case TextureFormat::Depth32f:
		return 4;
	case TextureFormat::Depth32fStencil8:
		return 5;
	case TextureFormat::RedGreenBlueAlpha32ui:
		return 16;
	case TextureFormat::RedGreenBlue32ui:
		return 12;
	case TextureFormat::RedGreenBlueAlpha16ui:
		return 8;
	case TextureFormat::RedGreenBlue16ui:
		return 6;
	case TextureFormat::RedGreenBlueAlpha8ui:
		return 4;
	case TextureFormat::RedGreenBlue8ui:
		return 3;
	case TextureFormat::RedGreenBlueAlpha32i:
		return 16;
	case TextureFormat::RedGreenBlue32i:
		return 12;
	case TextureFormat::RedGreenBlueAlpha16i:
		return 8;
	case TextureFormat::RedGreenBlue16i:
		return 6;
	case TextureFormat::RedGreenBlueAlpha8i:
		return 4;
	case TextureFormat::RedGreenBlue8i:
		return 3;
	}

	//TODO throw new ArgumentException("format");
	return 0;
}

int Renderer::Texture2DDescription::GetApproximateSizeInBytes() const
{
	return _width * _height * SizeInBytes(_format);
}

bool Renderer::Texture2DDescription::IsDepthStencilRenderable() const
{
	return (_format == TextureFormat::Depth24Stencil8 || _format == TextureFormat::Depth32fStencil8);
}

bool Renderer::Texture2DDescription::IsDepthRenderable() const
{
	return (_format == TextureFormat::Depth16 ||
		_format == TextureFormat::Depth24 ||
		_format == TextureFormat::Depth32f ||
		_format == TextureFormat::Depth24Stencil8 ||
		_format == TextureFormat::Depth32fStencil8);
}

bool Renderer::Texture2DDescription::IsColorRenderable() const
{
	return (!IsDepthRenderable() && !IsDepthStencilRenderable());
}

bool Renderer::Texture2DDescription::IsGernateMipmaps() const
{
	return _generateMipmaps;
}

Renderer::TextureFormat Renderer::Texture2DDescription::GetTextureFormat() const
{
	return _format;
}

int Renderer::Texture2DDescription::GetHeight() const
{
	return _height;
}

int Renderer::Texture2DDescription::GetWidth() const
{
	return _width;
}

Renderer::Texture2DDescription::Texture2DDescription(int width, int height, TextureFormat format, bool generateMipmaps)
{
	_width = width;
	_height = height;
	_format = format;
	_generateMipmaps = generateMipmaps;
}

Renderer::Texture2DDescription::Texture2DDescription(int width, int height, TextureFormat format) :Texture2DDescription(width, height, format, false)
{

}

Renderer::Texture2DDescription::Texture2DDescription()
{

}
